﻿using AutoMapper;
using Azure.Core;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography.X509Certificates;
using Windows.Infrastructure.EFCore.Share.Extensions;
using Windows.Infrastructure.Share.CustomException;
using Windows.Infrastructure.Share.Extensions;
using Windows.Infrastructure.Share.Security;
using Windows.Service.Share;
using Windows.WorkFlow.Domain;
using Windows.WorkFlow.Infrastructure.EFCore;

namespace Windows.WorkFlow.Service
{
    public class FlowService : IFlowService
    {
        private readonly IMapper _mapper;
        //private readonly ICache _cache;
        private readonly WorkFlowDbContext _db;
        private readonly ICurrentUser _currentUser;
        public FlowService(IMapper mapper, WorkFlowDbContext db, ICurrentUser currentUser)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
        }
        /// <summary>
        /// 流程视图
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResponse<FlowResponse>> Query(PageRequest<FlowRequest> request)
        {
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            var response = new PageResponse<FlowResponse>
            {
                TotalCount = await query.CountAsync(),
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                List = _mapper.Map<List<FlowResponse>>(list)
            };
            return response;
        }
        /// <summary>
        /// 获取id的流程详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<FlowResponse> Detail(int id)
        {
            var model = await _db.Flow.Include(x => x.FlowCategory).Include(x => x.Form).Include(x => x.Master_Flows).FindByIdAsync(id);
            return _mapper.Map<FlowResponse>(model);
        }
        /// <summary>
        /// 流程保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async System.Threading.Tasks.Task Save(FlowSaveRequest request)
        {
            if (await _db.Flow.AnyAsync(x => x.Name.ToLower() == request.Name && x.Id != request.Id))
                throw new ApiException("流程名称已存在!");
            Flow? model = _mapper.Map<Flow>(request);
            if (request.Id != null)
            {
                model = await _db.Flow.Include(x => x.Master_Flows).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("流程不存在!");
                model.Name = request.Name;
                model.EditorJson = request.EditorJson;
                model.Remark = request.Remark;
                _db.Master_Flow.RemoveRange(model.Master_Flows);
            }
            List<Master_Flow> list = new();
            AddMaster_Flow(request.RoleIds, MasterEnum.Role, list);
            AddMaster_Flow(request.OrganizationIds, MasterEnum.Organization, list);
            AddMaster_Flow(request.PostIds, MasterEnum.Post, list);
            AddMaster_Flow(request.PostLevelIds, MasterEnum.PostLevel, list);
            AddMaster_Flow(request.EmployeeIds, MasterEnum.Employee, list);
            if (list.Count > 0)
            {
                model.Master_Flows = list;
            }
            if (request.Id == null)
            {
                await _db.Flow.AddAsync(model);
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 流程删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task Remove(IdsRequest request)
        {
            //var names = await _db.PostLevel.Include(x => x.Posts).Where(x => request.Ids.Contains(x.Id) && x.Posts.Count > 0).Select(s => s.Name).ToListAsync();
            //if (names.Count > 0)
            //{
            //    throw new ApiException($"职级:{string.Join(',', names)}已被分配,不允许删除!");
            //}
            await _db.Flow.RemoveAsync(request.Ids);
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取当前用户可用的流程列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<FlowResponse>> GetCurrentCanUseFlows()
        {
            var flows = await (from a in _db.Flow.Include(x => x.FlowCategory).Include(x => x.Form)
                               from b in a.Master_Flows.DefaultIfEmpty()
                               where
                               (b.Type == MasterEnum.Role.ToInt() && _currentUser.RoleIds.Contains(b.MasterId))
                               || (b.Type == MasterEnum.Organization.ToInt() && _currentUser.OrganizationIds.Contains(b.MasterId))
                               || (b.Type == MasterEnum.Post.ToInt() && _currentUser.PostIds.Contains(b.MasterId))
                               || (b.Type == MasterEnum.PostLevel.ToInt() && _currentUser.PostLevelIds.Contains(b.MasterId))
                               || (b.Type == MasterEnum.Employee.ToInt() && b.MasterId == _currentUser.EmployeeId)
                               select a).Distinct().ToListAsync();
            return _mapper.Map<List<FlowResponse>>(flows);
        }
        /// <summary>
        /// 根据Id获取要发布的信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<FlowPublishResponse> GetFlowPublishInfo(long id)
        {
            var model = await _db.Flow.Include(x => x.Form).FindByIdAsync(id);
            return _mapper.Map<FlowPublishResponse>(model);
        }
        private IQueryable<Flow> Where(PageRequest<FlowRequest> request)
        {
            IQueryable<Flow> query = _db.Flow.Include(x => x.FlowCategory).Include(x => x.Form);
            if (!request.Query.Name.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Name.Contains(request.Query.Name!));
            }
            return query;
        }
        private void AddMaster_Flow(List<long>? masterIds, MasterEnum masterEnum,List<Master_Flow> list)
        {
            if (masterIds != null && masterIds.Count > 0)
            {
                masterIds.ForEach(item =>
                {
                    Master_Flow master_Flow = new()
                    {
                        Type = masterEnum.ToInt(),
                        MasterId = item
                    };
                    list.Add(master_Flow);
                });
            }
        }
    }
}
